package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.example.domain.ResponseResult;
import org.example.domain.dto.CityListDto;
import org.example.domain.entity.City;
import org.example.domain.vo.CitiesTitleVo;
import org.example.domain.vo.CityDetailVo;
import org.example.domain.vo.PageVo;
import org.example.enums.AppHttpCodeEnum;
import org.example.exception.SystemException;
import org.example.mapper.CityMapper;
import org.example.service.CityService;
import org.example.utils.BeanCopyUtils;
import org.example.utils.RedisCache;
import org.example.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;


import java.util.List;

@Service
@RequiredArgsConstructor
public class CityServiceImpl extends ServiceImpl<CityMapper, City> implements CityService {

    private final CityMapper cityMapper;

    private final RedisCache redisCache;

    @Override
    public ResponseResult addCity(City city) {

        List<City> cities = cityMapper.selectByCityName(city.getCityName());

        if(!CollectionUtils.isEmpty(cities)){
            throw new SystemException(AppHttpCodeEnum.CITY_NAME_EXITS);
        }
        Integer id = SecurityUtils.getUserId();
        city.setCreateBy(id);
        return ResponseResult.okResult(save(city));
    }

    @Override
    public ResponseResult cityList(CityListDto cityListDto) {

        LambdaQueryWrapper<City> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(cityListDto.getCityName()), City::getCityName,cityListDto.getCityName());
        if(cityListDto.getStatus() != null){
            queryWrapper.eq(City::getStatus,cityListDto.getStatus());
        }
        Page<City> page = new Page<>();
        page.setCurrent(cityListDto.getPageNum());
        page.setSize(cityListDto.getPageSize());
        page(page,queryWrapper);

        PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult selectAllCity() {
        List<City> cities = cityMapper.selectAllCity();
        return ResponseResult.okResult(cities);
    }

    @Override
    public ResponseResult updateCity(City city) {
        List<City> cities = cityMapper.selectByCityName(city.getCityName());
        if(cities.size()>=2){
            throw new SystemException(AppHttpCodeEnum.CITY_NAME_EXITS);
        }
        Integer id = SecurityUtils.getUserId();
        city.setUpdateBy(id);
        return ResponseResult.okResult(updateById(city));
    }

    @Override
    public ResponseResult getCityList(CityListDto cityListDto) {
        LambdaQueryWrapper<City> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(City::getStatus,0);
        Page<City> page = new Page<>();
        page.setCurrent(cityListDto.getPageNum());
        page.setSize(cityListDto.getPageSize());
        page(page,queryWrapper);

        PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getAllCities() {
        List<City> cities = cityMapper.getAllCities();
        List<CitiesTitleVo> citiesTitleVos = BeanCopyUtils.copyBeanList(cities, CitiesTitleVo.class);
        return ResponseResult.okResult(citiesTitleVos);
    }

    @Override
    public ResponseResult updateViewCount(Integer id) {
        redisCache.incrementCacheMapValue("CityViewCount",id.toString(),1);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getCityDetail(Integer id) {

        City city = getById(id);
        Integer cityViewCount = redisCache.getCacheMapValue("CityViewCount", id.toString());
        city.setViewCount(cityViewCount);

        CityDetailVo cityDetailVo = BeanCopyUtils.copyBean(city, CityDetailVo.class);
        return ResponseResult.okResult(cityDetailVo);
    }

    @Override
    public ResponseResult recommendCity() {
        LambdaQueryWrapper<City> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(City::getStatus,0);
        queryWrapper.orderByAsc(City::getViewCount);
        Page<City> page = new Page<>(1,5);
        page(page,queryWrapper);
        List<City> cities = page.getRecords();
        List<CitiesTitleVo> citiesTitleVos = BeanCopyUtils.copyBeanList(cities, CitiesTitleVo.class);
        return ResponseResult.okResult(citiesTitleVos);
    }
}
